Popular Searches
Popular Course Categories
Popular Courses

Understanding Initialization Order and Constructor Execution

Understanding Initialization Order and Constructor Execution

Access Modifiers, Static Members, and Final Keyword

Understanding Initialization Order and Constructor Execution in Java

Course: Core Java Training

Topic: Understanding Initialization Order and Constructor Execution

Course Link: Core Java Training Course

Demo Link: Register for a Course Demo

Website: JustAcademy


1. Introduction to Initialization Order and Constructor Execution

In Java, initialization order determines the sequence in which static variables, static initialization blocks, instance variables, instance initialization blocks, and constructors execute. Understanding this sequence helps developers predict how objects are created and how their fields receive values.

When a Java object is created, the JVM does not simply execute the constructor body immediately. It first ensures that the required classes have been initialized, allocates memory for the object, assigns default values to instance fields, and then follows a defined sequence involving superclass construction, instance initialization, and constructor execution.

This topic is particularly important when working with inheritance, overloaded constructors, field initializers, static blocks, and constructor chaining.

2. Learning Objectives

  • Understand the meaning of initialization order in Java.
  • Learn the difference between class initialization and object initialization.
  • Understand how static fields and static blocks execute.
  • Learn the order of instance field initialization and instance initialization blocks.
  • Understand how constructors execute in parent and child classes.
  • Explore constructor chaining with this() and super().
  • Understand how overloaded constructors work.
  • Identify common initialization mistakes and apply best practices.

3. What Is Initialization Order?

Initialization order is the predefined sequence in which Java prepares a class and initializes its objects. The order depends on whether the operation involves class-level members or instance-level members.

Java initialization can be divided into two main stages:

  • Class initialization: Static field initializers and static initialization blocks execute when a class is initialized.
  • Object initialization: Instance fields, instance initialization blocks, and constructors participate in initializing each new object.

Class initialization generally happens once for a particular class definition and class loader. Object initialization happens whenever a new instance is created.

4. Overview of the Java Initialization Sequence

4.1 Class Initialization

  1. The class is loaded when required.
  2. The class's static fields initially receive default values.
  3. Superclass initialization is completed before subclass initialization.
  4. Static field initializers and static initialization blocks execute in textual order.

4.2 Object Initialization

  1. Memory is allocated for the object, and instance fields receive default values.
  2. The superclass constructor chain is executed first.
  3. For each class in the hierarchy, its instance field initializers and instance initialization blocks execute in textual order after its superclass constructor has completed and before its own constructor body.
  4. The constructor body executes.
  5. Control returns to the subclass, where its instance initialization and constructor steps continue.

Important: Constructor chaining and superclass initialization affect the precise order. A subclass's instance field initializers and instance initialization blocks do not run before the superclass constructor has completed.

5. Default Values of Instance Variables

Before instance initialization code executes, Java assigns default values to the object's instance fields. This happens automatically when memory is allocated for the object.

Data Type Default Value
byte 0
short 0
int 0
long 0L
float 0.0f
double 0.0d
char '\u0000'
boolean false
Reference types null

Local variables declared inside methods do not receive automatic default values. They must be definitely assigned before they are read.

Example

public class DefaultValues {
    int number;
    boolean active;
    String name;

    public static void main(String[] args) {
        DefaultValues obj = new DefaultValues();

        System.out.println(obj.number);
        System.out.println(obj.active);
        System.out.println(obj.name);
    }
}

Output

0
false
null

Explanation: No explicit initial values are assigned to these fields. Java therefore gives them their respective default values before the constructor body runs.

6. Static Initialization Order

Static fields and static initialization blocks belong to the class rather than individual objects. During class initialization, static field initializers and static blocks execute in the order they appear in the class body.

Example

public class StaticOrder {
    static int first = 10;

    static {
        System.out.println("Static block executed");
    }

    static int second = 20;

    public static void main(String[] args) {
        System.out.println(first);
        System.out.println(second);
    }
}

Output

Static block executed
10
20

Explanation: The static field initializers and static block execute in textual order during class initialization. The main method runs after the class has been initialized.

7. Instance Variable Initialization Order

Instance variable initializers execute for every newly created object. They run in textual order, together with instance initialization blocks, after the superclass constructor has completed and before the constructor body for the current class.

Example

public class InstanceOrder {
    int first = 10;
    int second = 20;

    {
        System.out.println("Instance initialization block");
    }

    InstanceOrder() {
        System.out.println("Constructor executed");
    }

    public static void main(String[] args) {
        InstanceOrder obj = new InstanceOrder();
    }
}

Output

Instance initialization block
Constructor executed

Explanation: The field initializers assign values before the instance initialization block executes. The constructor body runs afterward. The field assignments do not produce output, so only the block and constructor messages appear.

8. Understanding Constructor Execution

A constructor is a special class member used to initialize a newly created object. Its name matches the class name, and it has no declared return type.

Constructors can initialize instance variables, validate input, establish object invariants, and prepare the object for use.

Example

public class Student {
    String name;
    int age;

    Student(String studentName, int studentAge) {
        name = studentName;
        age = studentAge;
        System.out.println("Constructor executed");
    }

    public static void main(String[] args) {
        Student s = new Student("Aarav", 21);

        System.out.println(s.name);
        System.out.println(s.age);
    }
}

Output

Constructor executed
Aarav
21

Explanation: The constructor receives the name and age as arguments and assigns them to the instance fields. Once the constructor finishes, the object can be used by the program.

9. Default Constructor and Parameterized Constructor

Java supports constructors with different parameter lists. A constructor without parameters is commonly called a no-argument constructor. If the programmer declares no constructors at all, the compiler normally provides a default no-argument constructor.

Feature No-Argument Constructor Parameterized Constructor
Parameters None One or more
Purpose Creates an object without caller-supplied initialization values. Accepts values to initialize the object.
Example Student() { } Student(String name) { }
Compiler-provided default Provided only if no constructor is declared. Not generated automatically.

Example

public class Book {
    String title;

    Book() {
        title = "Untitled";
    }

    Book(String bookTitle) {
        title = bookTitle;
    }

    public static void main(String[] args) {
        Book b1 = new Book();
        Book b2 = new Book("Java Basics");

        System.out.println(b1.title);
        System.out.println(b2.title);
    }
}

Output

Untitled
Java Basics

Explanation: The first object uses the no-argument constructor, while the second object uses the parameterized constructor. Each constructor establishes the object's initial title.

10. Constructor Chaining with this()

The this() keyword is used inside a constructor to invoke another constructor in the same class. This technique is called constructor chaining.

Constructor chaining helps avoid duplicating initialization logic. In Java, a this() constructor invocation must be the first statement in the constructor body, subject to the language rules for constructor prologues in newer Java versions.

Example

public class Employee {
    String name;
    int age;

    Employee() {
        this("Unknown", 0);
        System.out.println("No-argument constructor");
    }

    Employee(String employeeName, int employeeAge) {
        name = employeeName;
        age = employeeAge;
        System.out.println("Parameterized constructor");
    }

    public static void main(String[] args) {
        Employee e = new Employee();

        System.out.println(e.name);
        System.out.println(e.age);
    }
}

Output

Parameterized constructor
No-argument constructor
Unknown
0

Explanation: The no-argument constructor invokes the parameterized constructor using this("Unknown", 0). The parameterized constructor runs first, then control returns to the no-argument constructor.

11. Constructor Chaining with super()

The super() keyword invokes a constructor of the immediate superclass. It allows the parent class to initialize the part of an object inherited by the child class.

When a constructor does not explicitly invoke another constructor using this() or a superclass constructor using super(), Java ordinarily inserts an implicit no-argument superclass constructor invocation when permitted by the language rules. If the superclass has no accessible no-argument constructor, the subclass must explicitly invoke an appropriate superclass constructor.

Example

class Person {
    String name;

    Person(String personName) {
        name = personName;
        System.out.println("Person constructor");
    }
}

class Developer extends Person {
    String language;

    Developer(String personName, String programmingLanguage) {
        super(personName);
        language = programmingLanguage;
        System.out.println("Developer constructor");
    }
}

public class SuperDemo {
    public static void main(String[] args) {
        Developer d = new Developer("Maya", "Java");

        System.out.println(d.name);
        System.out.println(d.language);
    }
}

Output

Person constructor
Developer constructor
Maya
Java

Explanation: The Developer constructor calls super(personName). The Person constructor initializes the inherited name field before the rest of the Developer constructor body executes.

12. Initialization Order in Inheritance

When an object of a subclass is created, Java initializes the superclass portion of the object before completing the subclass's instance initialization and constructor body.

For a typical hierarchy where the superclass does not itself extend another application-defined class, the relevant order is:

  1. Class initialization occurs as required, including superclass initialization before subclass initialization.
  2. Memory is allocated and instance fields receive default values.
  3. The superclass constructor chain executes.
  4. The superclass's instance field initializers and instance initialization blocks execute at the appropriate point in its constructor process.
  5. The superclass constructor body executes.
  6. The subclass's instance field initializers and instance initialization blocks execute.
  7. The subclass constructor body executes.

Example

class Animal {
    int age = 5;

    Animal() {
        System.out.println("Animal constructor");
        System.out.println("Animal age: " + age);
    }
}

class Dog extends Animal {
    String breed = "Labrador";

    Dog() {
        System.out.println("Dog constructor");
        System.out.println("Dog breed: " + breed);
    }
}

public class InheritanceOrder {
    public static void main(String[] args) {
        Dog dog = new Dog();
    }
}

Output

Animal constructor
Animal age: 5
Dog constructor
Dog breed: Labrador

Explanation: The superclass constructor executes before the subclass's instance initialization and constructor body. The inherited field is initialized as part of the superclass initialization process, and the subclass field is initialized before the subclass constructor body runs.

13. Complete Example: Static, Instance, and Constructor Order

The following example demonstrates static initialization, instance initialization, and constructor execution in a single program.

class Parent {
    static {
        System.out.println("Parent static block");
    }

    {
        System.out.println("Parent instance block");
    }

    Parent() {
        System.out.println("Parent constructor");
    }
}

class Child extends Parent {
    static {
        System.out.println("Child static block");
    }

    {
        System.out.println("Child instance block");
    }

    Child() {
        System.out.println("Child constructor");
    }
}

public class CompleteOrder {
    public static void main(String[] args) {
        System.out.println("Main method started");

        Child c1 = new Child();
        System.out.println("--- Second object ---");
        Child c2 = new Child();
    }
}

Output

Parent static block
Child static block
Main method started
Parent instance block
Parent constructor
Child instance block
Child constructor
--- Second object ---
Parent instance block
Parent constructor
Child instance block
Child constructor

Explanation

  • The parent class is initialized before the child class, so the parent static block runs first.
  • The child static block runs next, before the main method begins executing its statements.
  • When the first object is created, the parent instance block and parent constructor execute before the child instance block and child constructor.
  • When the second object is created, the static blocks do not run again, but the instance blocks and constructors execute again.

14. Textual Order of Field Initializers and Instance Blocks

Within a class, instance field initializers and instance initialization blocks execute in the order in which they appear in the source code. The following example demonstrates why declaration order matters.

public class TextualOrder {
    int number = 10;

    {
        number = number + 5;
        System.out.println("Instance block: " + number);
    }

    int result = number * 2;

    TextualOrder() {
        System.out.println("Constructor number: " + number);
        System.out.println("Constructor result: " + result);
    }

    public static void main(String[] args) {
        new TextualOrder();
    }
}

Output

Instance block: 15
Constructor number: 15
Constructor result: 30

Explanation: The first field initializer assigns 10. The instance block increases it to 15. The later field initializer then calculates result as 15 * 2, giving 30. Finally, the constructor body prints the values.

15. Constructor Execution and Method Overriding

Calling an overridable instance method from a constructor can be dangerous. Java uses dynamic method dispatch, so a superclass constructor can invoke an overridden method in a subclass before the subclass's instance field initializers have executed.

Example

class Base {
    Base() {
        display();
    }

    void display() {
        System.out.println("Base display");
    }
}

class Derived extends Base {
    int value = 100;

    @Override
    void display() {
        System.out.println("Derived value: " + value);
    }
}

public class OverrideInitialization {
    public static void main(String[] args) {
        Derived d = new Derived();
        System.out.println("After construction: " + d.value);
    }
}

Output

Derived value: 0
After construction: 100

Explanation: The base constructor calls display(). Because the actual object is a Derived instance, Java dispatches the call to the overridden method in Derived. At that point, the derived field initializer value = 100 has not yet executed, so the field still contains its default value, 0.

Best practice: Avoid calling overridable methods from constructors. Doing so can expose partially initialized subclass state and produce unexpected behavior.

16. Common Mistakes in Initialization and Constructor Execution

  • Assuming constructors execute before field initializers: Instance field initializers and instance blocks execute before the constructor body for their class.
  • Ignoring superclass initialization: A superclass constructor must complete before subclass instance initialization and constructor execution continue.
  • Forgetting constructor chaining rules: A constructor invocation using this() or super() must follow the applicable Java language rules.
  • Assuming static blocks execute for every object: Static blocks run during class initialization, not on each object creation.
  • Relying on default values for business logic: Explicitly initialize important fields to make object state predictable.
  • Calling overridable methods from constructors: The subclass implementation may run before subclass fields have been initialized.
  • Overlooking textual order: Later field initializers may overwrite values assigned by earlier initialization blocks.
  • Failing to initialize required superclass state: Ensure the appropriate superclass constructor is invoked.

17. Best Practices for Initialization and Constructor Design

  • Initialize fields directly where they are declared when the initial value is simple.
  • Use constructors to validate input and establish a valid object state.
  • Use this() to reuse initialization logic within the same class.
  • Use super() to pass the necessary values to the superclass constructor.
  • Keep constructors concise and avoid performing lengthy or unpredictable operations inside them.
  • Avoid calling overridable methods from constructors.
  • Declare related field initializers and initialization blocks in a clear, logical order.
  • Use immutable fields and objects where possible to reduce unintended changes.
  • Write unit tests for important constructor paths and invalid input conditions.

18. Practice Exercises

  1. Create a class with two static fields, one static block, two instance fields, one instance block, and a constructor. Print messages to demonstrate their execution order.
  2. Create a parent class and a child class, each containing a static block, an instance block, and a constructor.
  3. Write a class with a no-argument constructor and two overloaded parameterized constructors.
  4. Use this() to chain two constructors in the same class.
  5. Use super() to initialize inherited fields through a parameterized parent constructor.
  6. Demonstrate how instance field initialization and an instance initialization block follow textual order.
  7. Write a program showing why calling an overridden method from a superclass constructor can produce unexpected output.
  8. Create two objects of the same class and identify which initialization steps execute once and which execute for each object.

19. Interview Questions and Answers

Q1. What is initialization order in Java?

Initialization order is the defined sequence in which static members, instance fields, initialization blocks, and constructors execute while a class and its objects are prepared for use.

Q2. What is the difference between class initialization and object initialization?

Class initialization prepares static class-level state. Object initialization prepares the instance-specific state of each newly created object.

Q3. Do instance variables receive default values before constructors execute?

Yes. Instance fields receive default values when the object is allocated, before explicit instance initialization and constructor bodies execute.

Q4. Which executes first: an instance initialization block or a constructor body?

For a given class, its instance field initializers and instance initialization blocks execute before its constructor body, after the superclass constructor has completed.

Q5. What is constructor chaining?

Constructor chaining means invoking another constructor to reuse initialization logic. The this() form invokes a constructor in the same class, while super() invokes a superclass constructor.

Q6. Why is super() used in Java?

super() invokes a constructor in the immediate superclass, allowing the inherited portion of an object to be initialized correctly.

Q7. Do static blocks execute again when a second object is created?

No. Static initialization blocks execute during class initialization. Instance initialization blocks and constructors execute for each newly created object.

Q8. In what order do parent and child constructors execute?

The superclass constructor chain executes first. After the superclass constructor completes, the subclass's instance initializers and instance blocks run, followed by the subclass constructor body.

Q9. What happens if a constructor calls an overridden method?

Java may execute the subclass's overridden method before the subclass's instance field initializers have run. This can expose default or incomplete values.

Q10. Does Java provide a default constructor automatically?

The compiler provides a default no-argument constructor when a class declares no constructor. If any constructor is declared explicitly, the compiler does not automatically add that default constructor.

Q11. Can constructor parameters initialize final instance fields?

Yes. A blank final instance field can be assigned during instance initialization or in a constructor, provided Java's definite-assignment rules are satisfied and the field is not assigned more than permitted.

Q12. Why is understanding initialization order important?

It helps prevent bugs involving inheritance, field values, constructor chaining, overridden methods, and unexpected initialization behavior.

20. Quick Revision Checklist

  • Static fields and static blocks execute during class initialization.
  • Superclass initialization precedes subclass initialization.
  • Instance fields receive default values when an object is allocated.
  • Superclass construction completes before subclass instance initializers and constructor body execute.
  • Instance field initializers and instance blocks execute in textual order.
  • Constructor bodies execute after the applicable instance initialization steps.
  • this() invokes another constructor in the same class.
  • super() invokes a constructor in the immediate superclass.
  • Static initialization generally happens once per class initialization, while instance initialization occurs for each object.
  • Avoid invoking overridable methods from constructors.
  • Initialize required fields explicitly and keep constructors easy to understand.

21. Conclusion

Understanding initialization order and constructor execution is essential for writing reliable Java programs. It explains how Java initializes class-level state, assigns default values, runs field initializers and initialization blocks, and executes constructor chains across inheritance hierarchies.

By learning the difference between static and instance initialization, understanding the roles of this() and super(), and following good constructor design practices, developers can create objects with predictable and valid states.

Continue learning Java fundamentals through the JustAcademy Core Java Training Course. You can also register for a course demo or visit the JustAcademy website for more information.

Previous Next
whatsapp